from flask import url_for
from sqlalchemy.exc import SQLAlchemyError
from werkzeug.security import generate_password_hash, check_password_hash
from ext import db
from datetime import datetime


class User(db.Model):
    """
    用户表
    """
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    email = db.Column(db.String(250), unique=True, nullable=False)  # 用户邮箱
    username = db.Column(db.String(45), unique=True, nullable=False)  # 用户姓名
    password = db.Column(db.String(128), nullable=False)  # 用户密码
    add_time = db.Column(db.DateTime, default=datetime.now)  # 注册时间
    login_time = db.Column(db.DateTime, onupdate=datetime.now, default=datetime.now)  # 登录时间
    is_active = db.Column(db.Boolean, default=True, nullable=False)  # 是否启用

    def __init__(self, username=None, password=None, email=None, is_active=True):
        self.username = username
        self.password = password
        self.email = email
        self.is_active = True

    def __str__(self):
        return "Users(id='%s')" % self.id

    def set_password(self, password):
        """ 加密用户注册时填写的密码 """
        return generate_password_hash(password)

    def check_password(self, hash, password):
        """ 用户登录时检查用户密码是否正确 """
        return check_password_hash(hash, password)

    def get(self, id):
        return self.query.filter_by(id=id).first()

    def add(self, user):
        db.session.add(user)
        return session_commit()

    def update(self):
        return session_commit()

    def delete(self, id):
        self.query.filter_by(id=id).delete()
        return session_commit()

    def to_json(self):
        json_post = {
            # 蓝图名称+视图函数名称
            'url': url_for('user_v1.create_user', id=self.id, _external=True),
            'email': self.email,
            'username': self.username,
            'add_time': self.add_time,
            'login_time': self.login_time,
            'is_active': self.is_active
        }
        return json_post


def session_commit():
    try:
        db.session.commit()
    except SQLAlchemyError as e:
        db.session.rollback()
        reason = str(e)
        return reason


class RevokedTokenModel(db.Model):
    """
    登出和注销表
    """
    __tablename__ = 'revoked_tokens'
    id = db.Column(db.Integer, primary_key=True)
    jti = db.Column(db.String(120))

    def add(self):
        db.session.add(self)
        db.session.commit()

    @classmethod
    def is_jti_blacklisted(cls, jti):
        query = cls.query.filter_by(jti=jti).first()
        return bool(query)


# 新建文章model
class Article(db.Model):
    """
    文章表
    """
    __tablename__ = 'article'
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    title = db.Column(db.String(20), nullable=False)  # 文章标题
    body = db.Column(db.String(255), nullable=False)  # 文章内容
    last_change_time = db.Column(db.DateTime, nullable=False)  # 最后一次修改日期
    author_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 作者
    author = db.relationship('User', backref=db.backref('articles'))


# 新建文章修改日志
class ChangeLogs(db.Model):
    """
    修改日志
    """
    __tablename__ = 'change_logs'
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    author_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 作者
    article_id = db.Column(db.Integer, db.ForeignKey('article.id'))  # 文章
    modify_content = db.Column(db.String(255), nullable=False)  # 修改内容
    create_time = db.Column(db.DateTime, nullable=False)  # 创建日期
